1 module unde.games.dizzy.omega.animations.meteorite;
2 
3 import derelict.opengl3.gl;
4 import std.format;
5 import std.random;
6 import std.stdio;
7 import unde.games.collision_detector;
8 import unde.games.dizzy.omega.dizzy;
9 import unde.games.dizzy.omega.bird;
10 import unde.games.dizzy.omega.main;
11 import unde.games.object;
12 import unde.games.renderer;
13 import unde.global_state;
14 
15 class Meteorite:StaticGameObject
16 {
17     Dizzy the_hero;
18     Random rnd;
19 
20     Vector start_pos, end_pos;
21     int number = 1;
22     float scale;
23     float rotation_speed;
24     Vector rotation_vector;
25 
26     this(MainGameObject root, Dizzy hero, Bird bird, Random _rnd)
27     {
28         frame = -1;
29         the_hero = hero;
30         rnd = _rnd;
31 
32         models["meteorite-01"] = root.models["meteorite-01"];
33         models["meteorite-02"] = root.models["meteorite-02"];
34         models["meteorite-03"] = root.models["meteorite-03"];
35 
36         collision_objects["solid"] = root.collision_objects["solid"];
37         super(root);
38     }
39 
40     override void draw(GlobalState gs)
41     {
42         float f = 0.0;   
43         if (frame >= 0)
44         {
45             f = root.frame - frame;
46         }
47 
48         glPushMatrix();
49         if (f <= 0.0) {}
50         else if (f <= 300.0)
51         {
52             glTranslatef(x, y, z);
53             glScalef(scale, scale, scale);
54             glRotatef(rotation_speed*f/300.0,
55                         rotation_vector.x,
56                         rotation_vector.y,
57                         rotation_vector.z);
58             recursive_render(gs, models[format("meteorite-%02d", number)]);
59         }
60         else {}
61         glPopMatrix();
62         
63     }
64 
65     override bool tick(GlobalState gs)
66     {
67         DizzyOmega dz = cast(DizzyOmega) root;
68         if (dz.wait_meteorite == 0 &&
69             root.frame < frame)
70         {
71             frame = root.frame - 301;
72         }
73 
74         if (dz.wait_meteorite2 == 0 &&
75             root.frame < frame)
76         {
77             frame = root.frame - 301;
78         }
79         
80         if (root.frame > frame + 300)
81         {
82             frame = root.frame + uniform(0, 1000, rnd);
83             start_pos.x = the_hero.x + uniform(-10.0, 10.0, rnd);
84             start_pos.y = 20.0;
85             start_pos.z = the_hero.z + uniform(-1.5, 1.5, rnd);
86 
87             end_pos.x = the_hero.x + uniform(-10.0, 10.0, rnd);
88             end_pos.y = -10.0;
89             end_pos.z = the_hero.z + uniform(-1.5, 1.5, rnd);
90 
91             number = uniform(1, 3, rnd);
92             scale = uniform(0.5, 2.0, rnd);
93 
94             rotation_speed = uniform(360.0, 3600.0, rnd);
95             rotation_vector.x = uniform(-1.0, 1.0, rnd);
96             rotation_vector.y = uniform(-1.0, 1.0, rnd);
97             rotation_vector.z = uniform(-1.0, 1.0, rnd);
98             
99             if (dz.wait_meteorite == 0)
100             {
101                 dz.wait_meteorite = 1;
102                 frame = root.frame;
103                 number = 1;
104                 start_pos.z = 0;
105                 end_pos.z = 0;
106                 end_pos.x = the_hero.x + uniform(5.0, 10.0, rnd);
107                 scale = 1.0;
108             }
109 
110             if (dz.wait_meteorite2 == 0)
111             {
112                 dz.wait_meteorite2 = 1;
113                 frame = root.frame;
114                 start_pos.z = 0;
115                 end_pos.z = 0;
116                 end_pos.x = dz.bird.x;
117                 end_pos.y = dz.bird.y;
118                 scale = 2.0;
119             }
120         }
121 
122         long mf = root.frame - frame;
123         if (frame >= 0 && mf >= 0 && mf <= 300)
124         {
125             x = start_pos.x + (end_pos.x - start_pos.x)*mf/300.0;
126             y = start_pos.y + (end_pos.y - start_pos.y)*mf/300.0;
127             z = start_pos.z + (end_pos.z - start_pos.z)*mf/300.0;
128 
129             float x0 = x-0.8*scale;
130             float x1 = x+0.8*scale;
131             float y0 = y-0.8*scale;
132             float y1 = y+0.8*scale;
133             float z0 = z-0.8*scale;
134             float z1 = z+0.8*scale;
135 
136             if (dz.wait_meteorite2 == 1)
137             {
138                 end_pos.x = dz.bird.x;
139                 end_pos.y = dz.bird.y;
140 
141                 if (mf == 300)
142                 {
143                     dz.wait_meteorite2 = 2;
144                     dz.bird.fall();
145                 }
146             }
147 
148             auto mb = if_intersect (collision_objects["solid"], [x0, y0, z0-4.0, x1, y1, z1+4.0]);
149             if (dz.wait_meteorite2 != 1 && mb > 0)
150             {
151                 frame = root.frame - 300;
152                 
153                 if (dz.wait_meteorite == 1)
154                 {
155                     dz.wait_meteorite = 2;
156                     dz.meteorite.x = x;
157                     dz.meteorite.y = y-0.8;
158                     dz.meteorite.z = z;
159                 }
160             }
161 
162             if ( (the_hero.x-1.0 < x0 && x0 < the_hero.x+1.0 || the_hero.x-1.0 < x1 && x1 < the_hero.x+1.0) &&
163                  (the_hero.y < y0 && y0 < the_hero.y+2.8 || the_hero.y < y1 && y1 < the_hero.y+2.8) && 
164                  (the_hero.z-1.0 < z0 && z0 < the_hero.z+1.0 || the_hero.z-1.0 < z1 && z1 < the_hero.z+1.0) )
165             {
166                 the_hero.energy -= 0.5*scale;
167                 if (the_hero.energy <= 0.0)
168                 {
169                     the_hero.die("Meteorite");
170                 }
171             }
172         }
173 
174         return true;
175     }
176 }    
177